/**
 * 文件名：@DefaultResultExtractParser.java <br/>
 * 包名：cn.efunbox.afw.core.mvc.result <br/>
 * 项目名：afw-core <br/>
 * @author xtwin <br/>
 */
package cn.efunbox.afw.core.mvc.result;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;

import org.apache.commons.beanutils.NestedNullException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import cn.efunbox.afw.core.resolver.Resolver;
import cn.efunbox.afw.core.util.MapUtil;
import cn.efunbox.afw.core.util.StringUtil;

/**
 * 类名：DefaultResultExtractParser  <br />
 *
 * 功能：
 *
 * @author xtwin <br />
 * 创建时间：2015年12月3日 下午5:56:08  <br />
 * @version 2015年12月3日
 */
public class DefaultResultExtractParser implements ResultExtractParser {
	
	// 日志记录器
	private static final Log logger = LogFactory.getLog(DefaultResultExtractParser.class);
	
	// 解析器
	//private ValueParserResolver valueParserResolver;
	private Resolver<ValueParser> valueParserResolver;

	// 解析器名称
	private String defaultResolver;
	
	private static final String KEY_DATA = "___data";

	/**
	 * 
	 * 功能: <br/>
	 * 
	 * 重写：xtwin <br/>
	 * 
	 * @version ：2015-7-23 上午10:43:27<br/>
	 * 
	 * @param context
	 * @param extract
	 * @return
	 * @throws Exception <br/>
	 * @see com.bocsd.cpfp.common.core.result.ResultExtractParser#parse(java.lang.Object, java.lang.String[])
	 */
	public Object parse(Object root, String[] extract) throws Exception {
		if (null != extract && extract.length > 0) {
			
			// 表达式提取缓存容器
			Map<String, Object> extMap = new TreeMap<String, Object>();
			
			// 对表达式进行拆分排序处理
			for (String ex : extract) {
				logger.debug("parse ex : " + ex);
				
				// 解析属性
				ex = ex.replace("[]", "").replace("[", ".[");
				
				int index = ex.replaceAll("\\{[^{}]+\\}", "").lastIndexOf('.');
				if (index != -1) {
					// 取出当前系列的前缀
					String prefix = ex.substring(0, index + 1);
					
					// 依次处理每个元素
					for (String p : ex.substring(index + 1).split("\\|")) {
						parseExact(prefix + p, extMap);
					}
				} else {
					parseExact(ex, extMap);
				}
			}
			
			return parseValue(root, extMap);
		}
		
		return null;
	}
	
	/**
	 * 
	 * 功能：解析结果 <br/>
	 *
	 * @author xtwin <br/>
	 * @version 2015-7-28 上午09:22:13 <br/>
	 */
	@SuppressWarnings("unchecked")
	public Object parseValue(Object root, Map<String, Object> extract) throws Exception {
		if (null != root) {
			
			Object[] roots = null;
			boolean flag = false;
			if (root instanceof Object[]) {
				roots = (Object[]) root;
				flag = true;
			} else if (root instanceof Collection) {
				roots = ((Collection<?>) root).toArray();
				flag = true;
			} else {
				roots = new Object[] { root };
				flag = false;
			}
			
			List<Object> rets = new ArrayList<Object>();
			
			for (Object data : roots) {
				
				Map<String, Object> datas = new HashMap<String, Object>();
				
				// 依次处理每个元素
				for (Entry<String, Object> ext : extract.entrySet()) {
					// 属性
					String property = ext.getKey();
					
					if (KEY_DATA.equals(property)) {
						// 跳过特殊属性
						continue;
					}
					
					Object value = null;
					try {
						Map<String, Object> next = (Map<String, Object>) ext.getValue();
						
						// 取出参数等信息
						//Object[] __data = (Object[]) next.remove(KEY_DATA);
						Object[] __data = (Object[]) next.get(KEY_DATA);
						
						String resolver = (String) __data[0];
						
						if (null == resolver) {
							resolver = defaultResolver;
						}
						
						ValueParser parser = valueParserResolver.resolve(resolver);
						
						// 对结果进行解析
						value = parser.parse(data, property, (Map<String, Object>) __data[1]);
						
						if (null != next && next.size() > 1) {
							value = parseValue(value, next);
						}
						
					} catch (NestedNullException e) {
						logger.warn(e.getMessage());
					}
					
					// 保存数据
					datas.put(property, value);
				}
				
				rets.add(datas);
			}
			
			return flag ? rets : rets.get(0);
		}
		
		return null;
	}
	
	/**
	 * 
	 * 功能：表达式解包 <br/>
	 *
	 * @author xtwin <br/>
	 * @version 2015-7-28 上午09:56:04 <br/>
	 */
	@SuppressWarnings("unchecked")
	private void parseExact(String ex, Map<String, Object> map) {
		int pIndex = ex.indexOf('{');
		
		int index_01 = ex.indexOf('.');
		if (pIndex != -1 && index_01 > pIndex) {
			index_01 = -1;
		}
		
		String property = null;
		if (index_01 != -1) {
			property = ex.substring(0, index_01);
			ex = ex.substring(index_01 +1);
		} else {
			property = ex;
		}
		
		int index_02 = property.indexOf(':');
		
		// 属性名称
		//String property = null;
		
		// 解析器名称
		String resolver = null;
		
		Map<String, Object> params = null;
		if (index_02 != -1) {
			
			// 检查是否配置了参数
			//int pIndex = property.indexOf("{", index_02);
			if (index_02 != -1) {
				// 包含参数部分
				params = MapUtil.toMapExp(property.substring(pIndex), "\\;");
				
				// 截取出解析器名称部分
				resolver = StringUtil.emptyAdjust(property.substring(index_02 + 1, pIndex));
			}
			
			// 截取出属性名称部分
			property = property.substring(0, index_02);
		}
		
		Object value = map.get(property);
		if (null == value) {
			value = new TreeMap<String, String>();
		}
		if (index_01 != -1) {
			parseExact(ex, (Map<String, Object>) value);
		}
		
		((Map<String, Object>) value).put(KEY_DATA, new Object[] { resolver, params });
		
		map.put(property, value);
	}

	/**
	 * @version 2015年12月3日-下午6:27:05
	 */
	public void setValueParserResolver(Resolver<ValueParser> valueParserResolver) {
		this.valueParserResolver = valueParserResolver;
	}

	/**
	 * @version 2015年12月3日-下午6:27:05
	 */
	public void setDefaultResolver(String defaultResolver) {
		this.defaultResolver = defaultResolver;
	}
}
